package net.youdi.gateway.handler.response;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: scl
 * @date: 2020-07-23 13:02
 * @description
 */
public class RewriteResponseHandler implements RewriteResponseHandlerFunction<Map, Object> {

    @Autowired(required = false)
    private List<ResponseDataHandler> responseDataHandlers;
    private final ObjectMapper objectMapper;

    public RewriteResponseHandler(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
        this.objectMapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(),true);
    }

    @Override
    public Publisher<Object> apply(ServerWebExchange exchange, Map resp) {
        Object data = resp.get("data");
        if (data != null  &&  responseDataHandlers != null && !responseDataHandlers.isEmpty()){
            if (!(data instanceof String)){
                try {
                    data = objectMapper.writeValueAsString(data);
                } catch (JsonProcessingException e) {
                }
            }
            Map container = new HashMap();
            for (ResponseDataHandler responseDataHandler : responseDataHandlers) {
                data = responseDataHandler.handler(exchange, (String) data,container);
            }
            if (data instanceof String){
                try {
                    data = objectMapper.readValue((String) data,Object.class);
                } catch (JsonProcessingException e) {
                }
            }
            resp.put("data",data);
            if (container.isEmpty()){
                resp.putAll(container);
            }
        }
        return Mono.just(resp);
    }

    public Publisher<Object> originWrite(Map resp) {
        try {
            return Mono.just(resp);
        } catch (Exception e) {
            return Mono.just(resp);
        }
    }
}
